/**
 * Copyright � 2012 GestureSoft. ALL RIGHTS RESERVED.
 * This file contains proprietary and GestureSoft CONFIDENTIAL Information.
 * Use, disclosure or reproduction is prohibited.
 * 
 * @fileName FacebookService.as
 * @creationDate Aug 8, 2012
 * @author 
 * @version 1.0
 */
package com.gesturesoft.imultimax.socialize.facebook
{
	
	
	import com.adobe.serialization.json.JSONDecoder;
	import com.gesturesoft.imultimax.socialize.org.osflash.signals.Signal;
	
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	

	public class FacebookService
	{
		private var __authURL:String;
		private var __appURL:String;
		private var __graphURL:String;
		private var __accessTokenURL:String;
		private var __userURL:String;
		private var __appName:String;
		private var __appID:String;
		private var __appSecret:String;
		private var __clientID:String;
		private var __accessToken:String;
		private var __userInfo:Array;
		private var __loggedIn:Boolean;
		
		public var errorSignal:Signal = new Signal();
		public var accessTokenReceived:Signal = new Signal();
		public var userInfoReceived:Signal = new Signal();
		public var postedToWall:Signal = new Signal();
		
		public function FacebookService()
		{
		}
		
		public function fetchAccessToken(code:String):void
		{
			var urlLoader:URLLoader = new URLLoader();
			urlLoader.addEventListener(Event.COMPLETE, onFetchAccesTokenComplete);
			
			var acURLStr:String = this.accessTokenURL+"?client_id=" +
				this.appID+"&redirect_uri=" +
				this.appURL+"&client_secret=" +
				this.appSecret+"&code=" +
				code;
			
			var urlRequest:URLRequest = new URLRequest(acURLStr);
			urlRequest.method = URLRequestMethod.GET;
			
			try {
				urlLoader.load(urlRequest);
			} catch(err:Error) {
				errorSignal.dispatch(err);
			}
		}
		
		protected function onFetchAccesTokenComplete(event:Event):void
		{
			var atAr:Array = String(event.target.data).split("access_token=");
			this.accessToken = String(atAr[1]);
			this.loggedIn = true;
			accessTokenReceived.dispatch();
			this.fetchUserInfo();
		}
		
		public function fetchUserInfo():void
		{
			var urlLoader:URLLoader = new URLLoader();
			urlLoader.addEventListener(Event.COMPLETE, onFetchUserInfoComplete);
			var urlRequest:URLRequest = new URLRequest(this.graphURL+"me/?access_token="+this.accessToken);
			urlRequest.method = URLRequestMethod.GET;
			
			try {
				urlLoader.load(urlRequest);
			} catch(err:Error) {
				errorSignal.dispatch(err);
			}
		}
		
		protected function onFetchUserInfoComplete(event:Event):void
		{
			var rawData:String = "["+String(event.target.data)+"]";
			this.userInfo = new JSONDecoder(rawData).getValue() as Array;
			
			this.userURL = this.graphURL+this.userInfo[0].id;
			
			userInfoReceived.dispatch(this.userInfo);
		}
		
		public function postToWall(post:String=null):void
		{
			var urlLoader:URLLoader = new URLLoader();
			urlLoader.addEventListener(Event.COMPLETE, onPostToWall);
			urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, onHTTPResponseStatus);
			urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHTTPStatus);
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
			urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
			
			var urlRequest:URLRequest = new URLRequest(this.userURL+"/feed/?access_token="+this.accessToken);
			urlRequest.method = URLRequestMethod.POST;
			
			var urlVariables:URLVariables = new URLVariables();
			urlVariables.message = post;
			
			urlRequest.data = urlVariables;
			
			try {
				urlLoader.load(urlRequest);
			} catch(err:Error) {
				errorSignal.dispatch(err);
			}
		}
		
		private function onHTTPResponseStatus(event:HTTPStatusEvent):void
		{
			trace("FacebookService::onHTTPResponseStatus: " + event.status);
		}
		
		private function onHTTPStatus(event:HTTPStatusEvent):void
		{
			trace("FacebookService::onHTTPStatus: " + event.status);
		}
		
		private function onError(event:ErrorEvent):void
		{
			trace("FacebookService::onError: " + event);
		}
		
		protected function onPostToWall(event:Event):void
		{
			var rawData:String = "["+String(event.target.data)+"]";
			var arr:Array = new JSONDecoder(rawData).getValue() as Array;
			
			if (arr[0].error) {
				errorSignal.dispatch(arr[0].error.message);
			} else {
				var idStr:String = arr[0].id as String;
				postedToWall.dispatch(idStr);	
			}
		}
		
		public function get authURL():String
		{
			return __authURL;
		}
		
		public function set authURL(val:String):void
		{
			__authURL = val;
		}
		
		public function get appURL():String
		{
			return __appURL;
		}
		
		public function set appURL(val:String):void
		{
			__appURL = val;
		}
		
		public function get graphURL():String
		{
			return __graphURL;
		}
		
		public function set graphURL(val:String):void
		{
			__graphURL = val;
		}
		
		public function get accessTokenURL():String
		{
			return __accessTokenURL;
		}
		
		public function set accessTokenURL(val:String):void
		{
			__accessTokenURL = val;
		}
		
		public function get userURL():String
		{
			return __userURL;
		}
		
		public function set userURL(val:String):void
		{
			__userURL = val;
		}
		
		public function get appName():String
		{
			return __appName;
		}
		
		public function set appName(val:String):void
		{
			__appName = val;
		}
		
		public function get appID():String
		{
			return __appID;
		}
		
		public function set appID(val:String):void
		{
			__appID = val;
		}
		
		public function get appSecret():String
		{
			return __appSecret;
		}
		
		public function set appSecret(val:String):void
		{
			__appSecret = val;
		}
		
		public function get clientID():String
		{
			return __clientID;
		}
		
		public function set clientID(val:String):void
		{
			__clientID = val;
		}
		
		public function get accessToken():String
		{
			return __accessToken;
		}
		
		public function set accessToken(val:String):void
		{
			__accessToken = val;
		}
		
		public function get userInfo():Array
		{
			return __userInfo;
		}
		
		public function set userInfo(val:Array):void
		{
			__userInfo = val;
		}
		
		public function get loggedIn():Boolean
		{
			return __loggedIn;
		}
		
		public function set loggedIn(val:Boolean):void
		{
			__loggedIn = val;
		}
		
	}
}